/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.controller;

//import com.thienloc.omap.entity.OmapUser;
import com.thienloc.omap.entity.OmapResource;
import com.thienloc.omap.entity.OmapRole;
import com.thienloc.omap.entity.OmapUser;
import com.thienloc.omap.entity.Permission;
import com.thienloc.omap.session.OmapUserFacade;
import com.thienloc.omap.util.JsfUtil;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import org.primefaces.model.MenuModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author GiangLT
 */
@ManagedBean(name = "sessionBean")
@SessionScoped
public class SessionBean implements Serializable {

    @EJB
    private OmapUserFacade omapUserFacade;
    @ManagedProperty(value = "#{applicationBean}")
    private ApplicationBean applicationBean;
    private MenuModel menuModel;
    private String currentLanguage = "vi_VN";
    private OmapUser omapUser;
    private boolean loggedIn = false;
    private int loginFailCount;
    private AtomicInteger broadcastInstantSeq = new AtomicInteger(1);
    private List<Permission> permissions;
    private final Logger logger = LoggerFactory.getLogger(SessionBean.class);

    /**
     * Creates a new instance of SessionBean
     */
    public SessionBean() {
    }

    @PostConstruct
    public void init() {
        omapUser = new OmapUser();
        loginFailCount = 0;
    }

    public String logout() {
        try {
            applicationBean.removeLoggedInUser(omapUser.getUsername());
            logger.debug("[{}] User logged out", omapUser.getUsername());
            omapUser = new OmapUser();
            permissions = null;
            loginFailCount = 0;
            loggedIn = false;
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
            session.removeAttribute("user");
            return "login?faces-redirect=true";
        } catch (Exception e) {
            JsfUtil.addErrorMessage("Đăng xuất thất bại", e.getMessage());
            return null;
        }
    }

    public String login() {
        try {
            OmapUser user = omapUserFacade.findByUsernameAndPassword(omapUser.getUsername(), omapUser.getPassword());
            if (user != null) {
//                if (applicationBean.isUserLoggedIn(user.getUsername())) {
//                    JsfUtil.addErrorMessage("Đã đăng nhập", "Tài khoản này đã đăng nhập từ máy khác");
//                    return "";
//                }
                applicationBean.addLoggedInUser(user);

                omapUser = user;
                loggedIn = true;
                loginFailCount = 0;

                FacesContext facesContext = FacesContext.getCurrentInstance();
                HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
                session.setAttribute("user", omapUser);

                logger.debug("[{}] User logged in", omapUser.getUsername());
                omapUser.setLastLoginDate(new Date());
                omapUserFacade.edit(omapUser);

                permissions = omapUser.getPermissionList();
                List<OmapRole> roles = omapUser.getOmapRoleList();
                for (OmapRole omapRole : roles) {
                    List<Permission> rolePermissions = omapRole.getPermissionList();
                    for (Permission rolePermission : rolePermissions) {
                        boolean found = false;
                        for (Permission userPermission : permissions) {
                            if (rolePermission.getAction().equals(userPermission.getAction())
                                    && rolePermission.getResourceId().getName().equals(userPermission.getResourceId().getName())) {
                                found = true;
                                break;
                            }
                        }
                        if (!found) {
                            permissions.add(rolePermission);
                        }
                    }
                }

                return "index?faces-redirect=true";
            } else {
                loginFailCount++;
                JsfUtil.addErrorMessage("Đăng nhập thất bại", "Sai tên đăng nhập hoặc mật khẩu");
                return "";
            }
        } catch (Exception e) {
            JsfUtil.addErrorMessage("Đăng nhập thất bại", e.getMessage());
            return "";
        }
    }

    public boolean hasRight(String resourceName, String action) {
        for (Permission permission : permissions) {
            if (permission.getResourceId().getName().equals(resourceName)
                    && permission.getAction().equals(action)) {
                return true;
            }
        }
        return false;
    }

    public List<String> getPermissions() {
        List<String> result = new ArrayList<String>(permissions.size());

        for (Permission permission : permissions) {
            result.add(permission.getResourceId().getName() + " - " + permission.getAction());
        }
        return result;
    }

    public void addPermission(String resourceName, String action) {
        OmapResource resource = new OmapResource();
        resource.setName(resourceName);
        Permission permission = new Permission();
        permission.setResourceId(resource);
        permission.setAction(action);

        permissions.add(permission);
    }

    public void authenticate() {
        if (!loggedIn) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            JsfUtil.redirectPage(facesContext, "faces/login.xhtml");
        }
    }

    public int getBroadcastInstantSeq() {
        int seq = broadcastInstantSeq.get();
        if (seq == Integer.MAX_VALUE) {
            broadcastInstantSeq.set(0);
        } else {
            broadcastInstantSeq.incrementAndGet();
        }
        return seq;
    }

    public void setBroadcastInstantSeq(AtomicInteger broadcastInstantSeq) {
        this.broadcastInstantSeq = broadcastInstantSeq;
    }

    //<editor-fold defaultstate="collapsed" desc="Setters & Getters">
    public String getCurrentLanguage() {
        return currentLanguage;
    }

    public void setCurrentLanguage(String currentLanguage) {
        this.currentLanguage = currentLanguage;
    }

    public boolean isLoggedIn() {
        return loggedIn;
    }

    public void setLoggedIn(boolean loggedIn) {
        this.loggedIn = loggedIn;
    }

    public int getLoginFailCount() {
        return loginFailCount;
    }

    public void setLoginFailCount(int loginFailCount) {
        this.loginFailCount = loginFailCount;
    }

    public OmapUser getOmapUser() {
        return omapUser;
    }

    public void setOmapUser(OmapUser omapUser) {
        this.omapUser = omapUser;
    }

    public MenuModel getMenuModel() {
        return menuModel;
    }

    public void setMenuModel(MenuModel menuModel) {
        this.menuModel = menuModel;
    }
    //</editor-fold>

    public ApplicationBean getApplicationBean() {
        return applicationBean;
    }

    public void setApplicationBean(ApplicationBean applicationBean) {
        this.applicationBean = applicationBean;
    }
}
